package com.arrogames.rgblabyrinth.game.panning {
	import ash.core.Engine;
	import ash.core.NodeList;
	import ash.core.System;
	
	import com.arrogames.lib.ash.movement.Direction;
	import com.arrogames.lib.ash.movement.Speed;
	import com.arrogames.rgblabyrinth.game.camera.CameraNode;
	import com.arrogames.rgblabyrinth.game.ui.GamePanel;
	
	import org.as3commons.logging.api.ILogger;
	import org.as3commons.logging.api.getLogger;
	
	import starling.display.Quad;
	import starling.filters.BlurFilter;
	import starling.utils.Color;
	
	public class MenuPanningSystem extends System {
		
		private static const LOG:ILogger = getLogger(MenuPanningSystem);
		
		private static const PANNING_ZOOM_LEVEL:Number = 2;
		
		private var panel:GamePanel;
		private var whiteGaze:Quad;
		private var previousZoom:Number;
		
		private var camera:CameraNode;
		
		private var SPEED:Number = 5;
		private var ANGLE:Number = 45;
		
		private var velX:Number;
		private var velY:Number;
		
		
		public function MenuPanningSystem(panel:GamePanel) {
			super();
			this.panel = panel;
			this.whiteGaze = new Quad(panel.width, panel.height, Color.WHITE);
			whiteGaze.alpha = .3;
		}
		
		override public function addToEngine(engine:Engine):void {
			super.addToEngine(engine);
			
			var cameras:NodeList = engine.getNodeList(CameraNode);
			cameras.nodeAdded.add(onCameraAdded);
			cameras.nodeRemoved.add(onCameraRemoved);
			
			if (cameras.head != null) {
				onCameraAdded(cameras.head as CameraNode);
			}
			
			panel.filter = new BlurFilter();
			panel.addChild(whiteGaze);
		}
		
		override public function removeFromEngine(engine:Engine):void {
			super.removeFromEngine(engine);
			panel.filter = null;
			panel.removeChild(whiteGaze);
			
			if (camera != null) {
				onCameraRemoved(camera);
			}
		}
		
		private function onCameraAdded(node:CameraNode):void {
			this.camera = node;
			previousZoom = node.camera.zoom;
			camera.camera.zoom = PANNING_ZOOM_LEVEL;
			
			velY = -Math.cos(ANGLE * Math.PI / 180) * SPEED;
			velX = Math.sin(ANGLE * Math.PI / 180) * SPEED;
		}
		
		private function onCameraRemoved(node:CameraNode):void {
			this.camera = null;
			camera.camera.zoom = previousZoom;
			camera.entity.remove(Speed);
			camera.entity.remove(Direction);
		}
		
		override public function update(time:Number):void {
			super.update(time);
			//http://jsfiddle.net/j5U5h/31/
			if (hasCamera()) {
				var maxX:Number = (800*camera.camera.zoom) - (camera.viewport.width);
				var maxY:Number = (600*camera.camera.zoom) - (camera.viewport.height);
				var minX:Number = 0;
				var minY:Number = 0;
				
				if (maxX > minX) {
					if (camera.position.x < minX || camera.position.x > maxX) {
						camera.position.x = camera.position.x > maxX ? maxX : minX;
						velX *= -1;
					}
					camera.position.x+=velX;
				}
				
				if (maxY > minY) {
					if (camera.position.y < minY || camera.position.y > maxY) {
						camera.position.y = camera.position.y > maxY ? maxY : minY;
						velY *= -1;
					}
					camera.position.y+=velY;
				}
			}
		}
		
		private function hasCamera():Boolean {
			return camera !== null;
		}
	}
}